﻿/*  CLR版本: 4.0.30319.18063
 * 系统时间: 2014/10/31 14:20:43
 * 创建年份: 2014
 *     作者: 程炜.Snail
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace Quick.Communicator
{
    /// <summary>
    /// TCP Server
    /// </summary>
    public class TCPServer
    {
        #region 属性
        /// <summary>
        /// 允许连接的最大客户端数量
        /// </summary>
        private int m_MaxConnectionsCount;
        /// <summary>
        /// Socket I/O缓冲区大小
        /// </summary>
        private int m_ReceiveBufferSize = 2048;
        private BufferManager m_BufferManager;
        /// <summary>
        /// 服务器端使用的Socket
        /// </summary>
        private Socket m_SvrSocket;
        /// <summary>
        ///  接收信号 SocketAsyncEventArgs 池
        /// </summary>
        private SocketAsyncEventArgsPool m_ReceiveSocketPool;
        /// <summary>
        /// 服务器的运行状态
        /// </summary>
        private bool m_IsRun = false;
        /// <summary>
        /// 超时时间(分钟)
        /// </summary>
        private int m_Timeouts = 10;
        /// <summary>
        /// 服务器程序监听的端口
        /// </summary>
        private int m_Port;
        /// <summary>
        /// 数据报文分析器
        /// </summary>
        private IResolver m_Resolver;

        /// <summary>
        /// 线程锁
        /// </summary>
        private ReaderWriterLock m_RWLS = new ReaderWriterLock();
        /// <summary>
        /// 保存所有客户端会话的表
        /// </summary>
        private Dictionary<EndPoint, Session> m_ClientSession = new Dictionary<EndPoint, Session>();
        /// <summary>
        /// 当前服务器运行开始共接收数据
        /// </summary>
        private Int64 m_TotalBytesRead;
        /// <summary>
        /// 当前客户端链接数
        /// </summary>
        private int m_NumConnectedSockets;
        /// <summary>
        /// 清除离线车辆定时器
        /// </summary>
        private Timer m_Timer;
        /// <summary>
        /// 发送服务器相关信息的计时器
        /// </summary>
        private Timer m_PromulgationEventTimer;
        private Semaphore m_MaxNumberAcceptedClients;
        /// <summary>
        /// 上一次链接的数据
        /// </summary>
        private int m_LastNumConnectedSockets;
        /// <summary>
        /// 上一次接收数据
        /// </summary>
        private Int64 m_LastTotalBytesRead;
        #endregion
        
        #region 属性
        /// <summary>
        /// 当前服务器是否运行
        /// </summary>
        public bool IsRunning
        {
            get { return m_IsRun; }
        }
        /// <summary>
        /// 当前服务器链接的客户端数量
        /// </summary>
        public int SessionCount
        {
            get { return m_ClientSession.Count; }
        }
        /// <summary>
        /// 客户端链接 Session
        /// </summary>
        public Dictionary<EndPoint, Session> ClientSession
        {
            get { return m_ClientSession; }
        }
        /// <summary>
        /// 系统使用的数据报文
        /// </summary>
        public IResolver Resolver
        {
            set { m_Resolver = value; }
            get { return m_Resolver; }
        }
        #endregion 

        #region 事件
        ///// <summary>
        ///// 服务器已经满事件
        ///// </summary>
        //public event NetEventHandler ServerFull;
        /// <summary>
        /// 客户端建立连接事件
        /// </summary>
        public event NetEventHandler ClientConn;
        /// <summary>
        /// 客户端关闭事件
        /// </summary>
        public event NetEventHandler ClientClose;
        /// <summary>
        /// 服务器配置变更
        /// </summary>
        public event NetEventHandler ServerConfigChange;
        /// <summary>
        /// 信号接收完成 事件
        /// </summary>
        public event ReceiveDataEndEventHandler ReceiveDataEnd;
        /// <summary>
        /// 信号发送完成 事件
        /// </summary>
        public event SendDataEndEventHandler SendDataEnd;
        /// <summary>
        /// 连接客户端数量发送改变
        /// </summary>
        public event ClientConnectionChangeEventHandler ClientConnectionChange;
        /// <summary>
        /// 服务器接收的客户端字节总数
        /// </summary>
        public event ReceiveTotalBytesEventHandler ReceiveTotalBytes;
        /// <summary>
        /// 是否禁止的IP
        /// </summary>
        public IsBanIPEventHandler IsBanIP;
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数(默认使用ASCII编码方式)
        /// </summary>
        /// <param name="port">服务器端监听的端口号</param>
        /// <param name="timeouts">链接超时时间(分钟)</param>
        /// <param name="resolver">报文解析器</param>
        public TCPServer(int port, int timeouts, IResolver resolver) : this(port, 50000, timeouts, resolver)
        { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="port">服务器端监听的端口号</param>
        /// <param name="maxClient">服务器能容纳客户端的最大能力</param>
        /// <param name="timeouts">链接超时时间(分钟)</param>
        /// <param name="resolver">报文解析器</param>
        public TCPServer(int port, int maxClient, int timeouts, IResolver resolver)
        {
            m_Port = port;
            m_MaxConnectionsCount = maxClient;
            m_Timeouts = timeouts;
            // 定时清除离线Socket
            m_Timer = new System.Threading.Timer(ClearOffTerminal, null, 0, 30000);

            m_PromulgationEventTimer = new System.Threading.Timer(OnPromulgationEvent, null, 0, 1000);

            m_Resolver = resolver;
            //最大连接 + 50 是为了使队列中多50个对象, 以便刚刚释放的对象不被立即使用
            m_BufferManager = new BufferManager(m_ReceiveBufferSize * (m_MaxConnectionsCount + 50), m_ReceiveBufferSize);
            m_ReceiveSocketPool = new SocketAsyncEventArgsPool();
            m_MaxNumberAcceptedClients = new Semaphore(m_MaxConnectionsCount, m_MaxConnectionsCount);
            m_BufferManager.InitBuffer();
            for (int i = 0; i < m_MaxConnectionsCount + 50; i++)
            {
                SocketAsyncEventArgs receiveEventArg = new SocketAsyncEventArgs();
                receiveEventArg.DisconnectReuseSocket = true;
                receiveEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
                m_BufferManager.SetBuffer(receiveEventArg);
                m_ReceiveSocketPool.Push(receiveEventArg);
            }
        }
        #endregion

        #region Socket方法
        /// <summary>
        /// 对外广播相关数据
        /// </summary>
        /// <param name="obj"></param>
        private void OnPromulgationEvent(object obj)
        {
            OnClientConnectionChange(obj);
            OnReceiveTotalBytes(obj);
        }
        /// <summary>
        /// 重新设置端口号,超时时间,报文解析器
        /// </summary>
        /// <param name="port">监听端口号</param>
        /// <param name="Timeouts">超时时间</param>
        /// <param name="resolver">报文解析器</param>
        public void SetSocketParameter(int port, int timeouts, IResolver resolver)
        {
            Stop();
            Thread.Sleep(1000);
            this.m_Port = port;
            this.m_Timeouts = timeouts;
            this.m_Resolver = resolver;
            OnServerConfigChange();
        }
        /// <summary>
        /// 开始监听指定端口
        /// </summary>
        public void Start()
        {
            if (m_IsRun)
            {
                return;
            }
            m_TotalBytesRead = 0L;
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, m_Port);
            m_SvrSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            m_SvrSocket.Bind(localEndPoint);
            m_SvrSocket.Listen(20);
            m_IsRun = true; //设定服务器为运行状态, 顺序与 StartAccept(null) 不能颠倒
            StartAccept(null);
        }
        /// <summary>
        /// 停止监听端口
        /// </summary>
        public void Stop()
        {
            if (m_IsRun)
            {
                m_IsRun = false;
                try
                {
                    m_SvrSocket.Shutdown(SocketShutdown.Both);
                }
                catch
                {  }
                //清理资源
                try
                {
                    m_SvrSocket.Close();
                }
                catch (Exception)
                {  }

                //关闭所有的客户端
                //将保存的所有的客户端会话信息清空
                CloseAllClient();
            }
        }
        /// <summary>
        /// 开始接收客户端链入请求
        /// </summary>
        /// <param name="acceptEventArg"></param>
        private void StartAccept(SocketAsyncEventArgs acceptEventArg)
        {
            m_MaxNumberAcceptedClients.WaitOne();
            if (!m_IsRun)
            {
                m_MaxNumberAcceptedClients.Release();
                return;
            }
            if (acceptEventArg == null)
            {
                acceptEventArg = new SocketAsyncEventArgs();
                acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
            }
            else
            {
                acceptEventArg.AcceptSocket = null;
            }
            try
            {
                bool willRaiseEvent = m_SvrSocket.AcceptAsync(acceptEventArg);
                if (!willRaiseEvent)
                {
                    ProcessAccept(acceptEventArg);
                }
            }
            catch (System.ObjectDisposedException ex)
            {

            }
        }
        /// <summary>
        /// 客户端连入请求完成,回调函数
        /// </summary>
        private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
        {
            ProcessAccept(e);
        }
        /// <summary>
        /// 处理客户端链入请求
        /// </summary>
        /// <param name="e"></param>
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            if (e.SocketError != SocketError.Success || !e.AcceptSocket.Connected)
            {
                int release = m_MaxNumberAcceptedClients.Release();
                Interlocked.Decrement(ref m_NumConnectedSockets);
                if (e.SocketError != SocketError.OperationAborted) //socket 关闭,不进行重新发起监听请求
                {
                    StartAccept(e);
                }
                return;
            }
            //进行IP限制
            if (null != IsBanIP && IsBanIP(e.AcceptSocket.RemoteEndPoint))
            {
                e.AcceptSocket.Disconnect(true);
                m_MaxNumberAcceptedClients.Release();
                StartAccept(e);
                return;
            }
            Interlocked.Increment(ref m_NumConnectedSockets);
            //获取接受的客户端连接，赋给ReadEventArg对象的UserToken。
            SocketAsyncEventArgs readEventArgs = null;
            bool willRaiseEvent = false;
            //SetPoolPop:
            //try
            //{
            readEventArgs = m_ReceiveSocketPool.Pop();
            readEventArgs.UserToken = e.AcceptSocket;

            //一旦客户端连接，提交一个连接接收。           
            willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
            if (!willRaiseEvent)
            {
                ProcessReceive(readEventArgs);
            }
            m_RWLS.AcquireWriterLock(1000);
            //m_RWLS.EnterWriteLock();
            try
            {
                Session session = new Session(readEventArgs, m_Timeouts);
                if (null != m_ClientSession && m_ClientSession.ContainsKey(e.AcceptSocket.RemoteEndPoint))
                {
                    Session oldSession = m_ClientSession[e.AcceptSocket.RemoteEndPoint];
                    CloseClientSocket(oldSession);
                    m_ClientSession[e.AcceptSocket.RemoteEndPoint] = session;
                }
                else
                {
                    m_ClientSession.Add(e.AcceptSocket.RemoteEndPoint, session);
                }
                OnClientConn(this, new NetEventArgs(session));
            }
            finally
            {
                m_RWLS.ReleaseWriterLock();
                //m_RWLS.ExitWriteLock();
            }
            StartAccept(e);
        }
        /// <summary>
        /// 用于完成异步操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IO_Completed(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;
                //case SocketAsyncOperation.Send:
                //    ProcessSend(e);
                //    break;
                //default:
                //    throw new ArgumentException("发送或接收操作异常");
            }
        }
        /// <summary>
        ///  当一个异步接收操作完成时调用该方法。  
        ///  如果远程主机关闭了连接，该Socket也关闭。  
        ///  如果收到数据，则回返到客户端。 
        /// </summary>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            // 检查远程主机是否关闭了连接。
            Socket userTokenSocket = e.UserToken as Socket;
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success && null != userTokenSocket)
            {
                //增加服务器接收的总字节数
                Interlocked.Add(ref m_TotalBytesRead, e.BytesTransferred);
                try
                {
                    //将接收到的数据暂存到Session中, 如果有相关数据,则进行拼接
                    if (null != ReceiveDataEnd)
                    {
                        Session sendDataSession = FindSession(userTokenSocket.RemoteEndPoint);
                        if (null == sendDataSession)
                        {
                            return;
                        }
                        sendDataSession.LastConnectionTime = DateTime.Now;

                        byte[] receivedByte = new byte[e.BytesTransferred];
                        Array.Copy(e.Buffer, e.Offset, receivedByte, 0, e.BytesTransferred);

                        // 如果没有报文结束符标记,则直接进行数据转发
                        if (string.IsNullOrEmpty(m_Resolver.EndTag) && string.IsNullOrEmpty(m_Resolver.HexStringEndTag))
                        {
                            //深拷贝,为了保持Datagram的对立性
                            ICloneable copySession = (ICloneable)sendDataSession;
                            Session clientSession = (Session)copySession.Clone();
                            clientSession.DatagramByte = receivedByte;
                            clientSession.Datagram = this.m_Resolver.DatagramDesEncoding(receivedByte);
                            //发布一个报文消息
                            OnReceiveSignalEnd(this, new NetEventArgs(clientSession));
                        }
                        else //存在报文结束符,则需要进行分割
                        {
                            string receivedData = this.m_Resolver.ByteToHexString(receivedByte);

                            if (!string.IsNullOrEmpty(sendDataSession.SpareDatagram) && sendDataSession.SpareDatagram.Length != 0)
                            {
                                //加上最后一次通讯剩余的报文片断
                                receivedData = string.Concat(sendDataSession.SpareDatagram, ",", receivedData);
                            }
                            string[] recvDatagrams = m_Resolver.Resolve(ref receivedData);
                            //剩余的代码片断,下次接收的时候使用
                            sendDataSession.SpareDatagram = receivedData;
                            receivedData = null;
                            foreach (string newDatagram in recvDatagrams)
                            {
                                //深拷贝,为了保持Datagram的对立性
                                ICloneable copySession = (ICloneable)sendDataSession;
                                Session clientSession = (Session)copySession.Clone();
                                clientSession.DatagramByte = this.m_Resolver.HexStringToByte(newDatagram);
                                clientSession.Datagram = this.m_Resolver.DatagramDesEncoding(clientSession.DatagramByte);
                                //发布一个报文消息
                                OnReceiveSignalEnd(this, new NetEventArgs(clientSession));
                            }
                            if (sendDataSession.SpareDatagram.Length > m_ReceiveBufferSize)
                            {
                                sendDataSession.SpareDatagram = string.Empty;
                            }
                        } //end of if(ReceiveSignalEnd != null)
                    }
                    //收完数据后,进行下一次接收
                    if (!userTokenSocket.ReceiveAsync(e))
                    {
                        ProcessReceive(e);
                    }
                }
                catch
                {
                    try
                    {
                        CloseClientSocket(FindSession(((Socket)e.UserToken).RemoteEndPoint));
                    }
                    catch
                    { }
                }
            }
            else
            {
                if (null != e.UserToken)
                {
                    try
                    {
                        CloseClientSocket(FindSession(((Socket)e.UserToken).RemoteEndPoint));
                    }
                    catch
                    { }
                }
            }
        }
        /// <summary>
        /// 关闭所有的客户端会话,与所有的客户端连接会断开
        /// </summary>
        public void CloseAllClient()
        {
            List<Session> sessionList = new List<Session>();
            sessionList.AddRange(m_ClientSession.Values);
            foreach(Session session in sessionList)
            {
                CloseClientSocket(session);
            }
            sessionList.Clear();
            sessionList = null;
        }
        /// <summary>
        /// 关闭指定Session客户端
        /// </summary>
        /// <param name="session"></param>
        public void CloseClientSocket(Session session)
        {
            if (null == session || null == session.ID) //调整顺序3  2014-8-14(不知道之前为何将判断为空放在释放计数的下面,现在先调整,试用一段时间看有无异常)
            {
                return;
            }

            m_MaxNumberAcceptedClients.Release(); //调整顺序1  2014-8-14(之前这是在判断为空的上面)
            Interlocked.Decrement(ref m_NumConnectedSockets);//调整顺序2  2014-8-14(之前这是在判断为空的上面)


            OnClientClose(this, new NetEventArgs(session));
            //当前是否已经进入锁模式,防止递归调用
            bool isEnterWriteLock = m_RWLS.IsWriterLockHeld; //;.IsWriteLockHeld;
            if (!isEnterWriteLock)
            {
                m_RWLS.AcquireWriterLock(1000); //.EnterWriteLock();
            }
            try
            {
                if (m_ClientSession.ContainsKey(session.ID))
                {
                    session.Datagram = null;
                    session.DatagramByte = null;
                    m_ClientSession.Remove(session.ID);
                }
            }
            finally
            {
                if (!isEnterWriteLock && m_RWLS.IsWriterLockHeld)
                {
                    m_RWLS.ReleaseWriterLock();
                }
            }
            SocketAsyncEventArgs receiveSaea = session.ClientSocketAsyncEventArgs;
            Socket userTokenSocket = receiveSaea.UserToken as Socket;
            if (null != userTokenSocket)
            {
                try
                {
                    try
                    {
                        userTokenSocket.Shutdown(SocketShutdown.Both);
                    }
                    catch (Exception)
                    { }
                    userTokenSocket.Close();
                    //userTokenSocket.DisconnectAsync(receiveSaea);
                }
                catch
                { }
            }            
            receiveSaea.UserToken = null;
            m_ReceiveSocketPool.Push(receiveSaea);
        }
        /// <summary>
        /// 关闭指定客户端
        /// </summary>
        /// <param name="endPoint"></param>
        public void CloseClientSocket(EndPoint endPoint)
        {
            CloseClientSocket(FindSession(endPoint));
        }
        /// <summary>
        /// 查找或创建Session对象
        /// 如果未查找到对应的Session对象,则创建一个新的Session返回,
        /// 并将新创建的对象存入 ClientSession对象中
        /// </summary>
        /// <param name="cliSock"></param>
        /// <returns></returns>
        private Session FindSession(EndPoint endPoint)
        {
            if (null == endPoint)
            {
                return null;
            }
            m_RWLS.AcquireWriterLock(1000);
            try
            {
                Session session;
                if (this.m_ClientSession.TryGetValue(endPoint, out session))
                {
                    return session;
                }
                return null;
            }
            finally
            {
                m_RWLS.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// 服务器端发送数据的方法
        /// 如有设置报文结束符,则会添加报文结束符
        /// </summary>
        /// <param name="endPoint">数据的IP地址</param>
        /// <param name="datagram">需发送的报文数据(不包含报文结束符)</param>
        /// <param name="isCloseSession">发送完成后进行断开链接</param>
        public virtual bool AsyncSend(EndPoint endPoint, string datagram, bool isAddEndTag = true, bool isCloseSession = false)
        {
            byte[] bt = this.m_Resolver.DatagramEncodingBarringEngTag(datagram);
            return AsyncSend(endPoint, bt, isAddEndTag, isCloseSession);
        }
        /// <summary>
        /// 服务器端发送数据的方法
        /// </summary>
        /// <param name="endPoint"></param>
        /// <param name="bt"></param>
        /// <param name="isAddEndTag">是否自动添加结束符</param>
        /// <param name="isCloseSession">发送完成后进行断开链接</param>
        public virtual bool AsyncSend(EndPoint endPoint, byte[] bt, bool isAddEndTag = true, bool isCloseSession = false)
        {
            Session session = FindSession(endPoint);
            return AsyncSend(session, bt, isAddEndTag, isCloseSession);
        }
        /// <summary>
        /// 服务器端发送数据的方法
        /// </summary>
        /// <param name="recvDataClient">接收数据的客户端会话（特定的客户）</param>
        /// <param name="datagram">需发送的报文数据(不包含报文结束符)</param>
        /// <param name="isAddEndTag">是否自动添加结束符</param>
        /// <param name="isCloseSession">发送完成后进行断开链接</param>
        public virtual bool AsyncSend(Session recvDataClient, string datagram, bool isAddEndTag = true, bool isCloseSession = false)
        {
            byte[] bt = this.m_Resolver.DatagramEncodingBarringEngTag(datagram);
            return AsyncSend(recvDataClient, bt, isAddEndTag, isCloseSession);
        }
        /// <summary>
        /// 服务器端发送数据的方法
        /// </summary>
        /// <param name="recvDataClient">接收数据的客户端会话（特定的客户）</param>
        /// <param name="bt">数据报文(不包含报文结束符)</param>
        /// <param name="isAddEndTag">是否自动添加结束符</param>
        /// <param name="isCloseSession">发送完成后进行断开链接</param>
        public virtual bool AsyncSend(Session recvDataClient, byte[] bt, bool isAddEndTag = true, bool isCloseSession = false)
        {
            if (null == recvDataClient)
            {
                return false;
            }
            if (isAddEndTag)
            {
                bt = this.m_Resolver.DatagramAddEndTag(bt);
            }
            Socket socket = recvDataClient.ClientSocketAsyncEventArgs.UserToken as Socket;
            socket.Send(bt);
            if (isCloseSession)
            {
                CloseClientSocket(socket.RemoteEndPoint);
            }
            return true;
        }
        /// <summary>
        /// 发送数据完成处理函数,并断开与客户端的链接
        /// </summary>
        /// <param name="iar">目标客户端Socket</param>
        protected virtual void SendDataEndAndCloseSessionAsyncResult(IAsyncResult iar)
        {
            try
            {
                SocketAsyncEventArgs args = (SocketAsyncEventArgs)iar.AsyncState;
                Socket client = args.UserToken as Socket;
                client.EndSend(iar);
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Success));
                Thread.Sleep(500);//休眠 500 毫秒, 防止数据缓冲区还未发送完
                try
                {
                    CloseClientSocket(FindSession(client.RemoteEndPoint));
                }
                catch 
                { }
            }
            catch
            {
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Failure));
            }
        }
        /// <summary>
        /// 发送数据完成处理函数
        /// </summary>
        /// <param name="iar">目标客户端Socket</param>
        protected virtual void SendDataEndAsyncResult(IAsyncResult iar)
        {
            SocketAsyncEventArgs args = (SocketAsyncEventArgs)iar.AsyncState;
            Socket client = args.UserToken as Socket;
            try
            {
                int sent = client.EndSend(iar);
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Success));
            }
            catch
            {
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Failure));
                try
                {
                    CloseClientSocket(FindSession(client.RemoteEndPoint));
                }
                catch
                { }
            }
        }
        /// <summary>
        /// 清除已经离线设备
        /// </summary>
        /// <param name="obj"></param>
        private void ClearOffTerminal(object obj)
        {
            if (null != this.m_ClientSession && this.m_ClientSession.Count > 0 && this.m_Timeouts > 0)
            {
                try
                {
                    List<EndPoint> list = new List<EndPoint>();
                    IPEndPoint[] tmpIpept = new IPEndPoint[this.m_ClientSession.Keys.Count];
                    this.m_ClientSession.Keys.CopyTo(tmpIpept, 0);
                    bool IsBanIPNotNull = IsBanIP!=null; //新增 BanIP 禁止
                    foreach (EndPoint id in tmpIpept)
                    {
                        Session session = null;
                        if (null != id && this.m_ClientSession.TryGetValue(id, out session))
                        {
                            if ((IsBanIPNotNull && IsBanIP(id)) || (DateTime.Now - session.LastConnectionTime) > session.Timeouts)
                            {
                                list.Add(id);
                            }
                        }
                    }
                    foreach (EndPoint id in list)
                    {
                        Session session = null;
                        if (this.m_ClientSession.TryGetValue(id, out session))
                        {
                            CloseClientSocket(session);
                        }
                    }
                    m_NumConnectedSockets = m_ClientSession.Count;
                }
                catch
                { }
            }
        }
        #endregion

        #region 事件触发
        /// <summary>
        /// 数据报文发送完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSendCommandEnd(object sender, SendStateEventArgs e)
        {
            if (SendDataEnd != null)
            {
                Delegate[] delegateList = SendDataEnd.GetInvocationList();
                foreach (SendDataEndEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// 新的客户端连接,发出通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnClientConn(object sender, NetEventArgs e)
        {
            if (ClientConn != null)
            {
                Delegate[] delegateList = ClientConn.GetInvocationList();
                foreach (NetEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// Client 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnClientClose(object sender, NetEventArgs e)
        {
            if (null != ClientClose)
            {
                Delegate[] delegateList =ClientClose.GetInvocationList();
                foreach (NetEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// 信号接收完成 事件,通知相关订阅者
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnReceiveSignalEnd(object sender, NetEventArgs e)
        {
            if (null != ReceiveDataEnd)
            {
                Delegate[] delegateList = ReceiveDataEnd.GetInvocationList();
                foreach (ReceiveDataEndEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// 配置变更
        /// </summary>
        private void OnServerConfigChange()
        {
            if (null != ServerConfigChange)
            {
                Delegate[] delegateList = ServerConfigChange.GetInvocationList();
                foreach (NetEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(this, null, null, null);
                }
            }
        }
        /// <summary>
        /// Client 连接发送改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnClientConnectionChange(object sender)
        {
            if (m_LastNumConnectedSockets != m_NumConnectedSockets)
            {
                m_LastNumConnectedSockets = m_NumConnectedSockets;
            }
            else
            {   //数据没改变,不进行发送
                return;
            }
            if (null != ClientConnectionChange)
            {
                ConnectCountEventArgs e = new ConnectCountEventArgs(m_NumConnectedSockets);
                Delegate[] delegateList = ClientConnectionChange.GetInvocationList();
                foreach (ClientConnectionChangeEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }        
         /// <summary>
        /// 服务器接收字节总数
        /// </summary>
        /// <param name="sender"></param>
        private void OnReceiveTotalBytes(object sender)
        {
            if (m_LastTotalBytesRead != m_TotalBytesRead)
            {
                m_LastTotalBytesRead = m_TotalBytesRead;
            }
            else
            {   //数据没改变,不进行发送
                return;
            }
            if (null != ReceiveTotalBytes)
            {
                ReceiveTotalBytesEventArgs e = new ReceiveTotalBytesEventArgs(m_TotalBytesRead);
                Delegate[] delegateList = ReceiveTotalBytes.GetInvocationList();
                foreach (ReceiveTotalBytesEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        #endregion
    }
}
